import sys,traceback
from django.conf import settings
from utils.utils import get_client_ip
from log.models import LogError


# 存在外键约束，不能删除
class ForeignkeyConstraintError(Exception):
    def __init__(self, ErrorInfo="存在外键约束，不能删除"):
        self.errorinfo = ErrorInfo

    def __str__(self):
        return self.errorinfo


class LogErrorDB:
    '''
    记录异常信息
    '''
    def __init__(self, req):
        self.req = req

    # 获取各种请求的参数
    def getData(self):
        all = self.req.query_params.__len__() and (self.req.FILES.__len__() or self.req.data.__len__())
        data = '' 
        if all:
            data += 'params参数：'

        if self.req.query_params.__len__():
            data += str(self.req.query_params.dict())   # params参数

        if self.req.FILES.__len__():
            data += '\n' + 'data参数：' if all else ''
            if self.req.data.__len__():
                data += str(self.req.data.update(self.req.FILES.dict())) # 上传文件及data参数
            else:
                data += str(self.req.data)                  # data参数

        if self.req.FILES.__len__()==0 and self.req.data.__len__():
            data += '\n' + 'data参数：' if all else ''
            data += str(self.req.data)                  # data参数
        return data
    
    '''
    返回异常信息
    :param name: 返回指定键值
    '''
    def errInfo(self, name=None):
        data = {
            "exc_stack": traceback.format_exc(),       # 错误栈帧信息
            "exc_type": str(sys.exc_info()[0])[8:-2],    # 异常类
            "exc_value": sys.exc_info()[1].__str__(),    # 异常描述
        }
        return data.get(name) if name else data

    # 日志信息保存到数据库  
    def saveDB(self):        
        log = LogError(**{
            "env": 1 if settings.DEBUG else 2,                  # 由系统字典表env编号字典决定
            "visitorIp": get_client_ip(self.req),               # 访问者ip
            "method": self.req.META['REQUEST_METHOD'],          # 请求方式
            "url": self.req.path,                               # 接口
            "userAgent": self.req.META['HTTP_USER_AGENT'],      # 浏览器UserAgent
            "message": self.errInfo('exc_stack'),               # 异常栈帧信息
            "exceptionClass": self.errInfo('exc_type'),         # 异常类
            "data": self.getData(),                             # 请求参数
            "userId_id": self.req.user.pk or None
        })
        log.save()